package com.csjy.migration.hnnd.business;

import com.csjy.migration.hnnd.*;
import com.csjy.migration.hnnd.annotation.BusinessDataConverter;
import com.csjy.migration.hnnd.dict.Bank;
import com.csjy.migration.hnnd.dict.RepayType;

import javax.script.ScriptException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@BusinessDataConverter(
    auto = false,
    insertSql = "INSERT INTO ND_BPM_CREDIT_EXTENSION_SC\n" +
        "(ID, CREATE_NAME, CREATE_BY, CREATE_DATE, UPDATE_NAME, UPDATE_BY, UPDATE_DATE, SYS_ORG_CODE, SYS_COMPANY_CODE, BPM_STATUS, PRO_ID, AUDIT_FLOW_NO, ORIG_ENDDATE, PRO_BALANCE, EXTENSION_ENDDATE, CUSTOM_APPLY_REASON, BANK_OPINION, EFFECTIVE_DATE, PROC_ID, LENDING_ID, TASK_ID, TASK_DEF_KEY, SOURCE_ID)\n" +
        "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    updateSql = "UPDATE ND_BPM_CREDIT_EXTENSION_SC\n" +
        "SET CREATE_NAME=?, CREATE_BY=?, CREATE_DATE=?, UPDATE_NAME=?, UPDATE_BY=?, UPDATE_DATE=?, SYS_ORG_CODE=?, SYS_COMPANY_CODE=?, BPM_STATUS=?, PRO_ID=?, AUDIT_FLOW_NO=?, ORIG_ENDDATE=?, PRO_BALANCE=?, EXTENSION_ENDDATE=?, CUSTOM_APPLY_REASON=?, BANK_OPINION=?, EFFECTIVE_DATE=?, PROC_ID=?, LENDING_ID=?, TASK_ID=?, TASK_DEF_KEY=?, SOURCE_ID=?\n" +
        "WHERE ID = ?",
    findMigratedIdListSql = "SELECT ID FROM ND_BPM_CREDIT_EXTENSION_SC WHERE PROC_ID = ?"
)
public class NdBpmCreditExtensionSc extends AbstractWorkflowBusiness {


  public NdBpmCreditExtensionSc(DbUtil sourceDbUtil, DbUtil targetDbUtil, SourceBusinessData sourceData, ProgramArgument programArgument, String projectId, String procInstId) throws SQLException {
    super(sourceDbUtil, targetDbUtil, sourceData, programArgument, projectId, procInstId);
  }

  @Override
  public void migrate() throws Exception {
    List<Map> btItemAccountDeferRecList = this.sourceData.getBtItemAccountDeferRec().stream()
        .filter(btItemDeferRec->{
          if(btItemDeferRec.get("WORKFLOWNO") == null) {
            return false;
          }
          String workflowNo = btItemDeferRec.get("WORKFLOWNO").toString();
          return workflowNo.equals(this.procInstId);
        })
        .collect(Collectors.toList());

    Optional<Map> btItemDeferRecOptional = this.sourceData.getBtItemDeferRec().stream()
        .filter(btItemDeferRec->{
          if(btItemDeferRec.get("WORKFLOWNO") == null) {
            return false;
          }
          String workflowNo = btItemDeferRec.get("WORKFLOWNO").toString();
          return workflowNo.equals(this.procInstId);
        })
        .findFirst();
    Map btItemDeferRec = btItemDeferRecOptional.isPresent() ? btItemDeferRecOptional.get() : null;
    for(Map.Entry<String,Map<String,Object>> entry : taskParamMap.entrySet()) {
      String curJbpmTaskInstanceId = entry.getKey();
      Map<String,Object> taskParam = entry.getValue();

      for (Map row : btItemAccountDeferRecList) {
        try {
          String id = MD5Utils.stringToMD5(this.projectId + this.procInstId + curJbpmTaskInstanceId);
          // 判断是否需要覆盖迁移
          int needMigratedResult = this.needMigrated(id);
          if(needMigratedResult == 0) {
            continue;
          }

          // 单条插入或更新
          if(needMigratedResult == 1) {
            this.targetDbUtil.updateByParams(updateSql,this.buildValues(row,btItemDeferRec,id, curJbpmTaskInstanceId, taskParam),true);
          } else {
            this.targetDbUtil.updateByParams(insertSql,this.buildValues(row,btItemDeferRec,id, curJbpmTaskInstanceId, taskParam));
          }
        } catch(Exception e) {
          throw new Exception(String.format("流程实例[%s]-放款台账展期数据迁移失败:%s\n",this.procInstId, curJbpmTaskInstanceId, e.getMessage()));
        }
      }
    }
  }

  public List buildValues(Map btItemAccountDeferRec,Map btItemDeferRec, String id, String curJbpmTaskInstanceId, Map<String,Object> taskParam) throws Exception {
    List values = new ArrayList();
    //ID	主键
    values.add(id);
    //CREATE_NAME	创建人名称
    values.add(null);
    //CREATE_BY	创建人登录名称
    values.add(null);
    //CREATE_DATE	创建日期
    values.add(btItemAccountDeferRec.get("CREATE_TIME"));
    //UPDATE_NAME	更新人名称
    values.add(null);
    //UPDATE_BY	更新人登录名称
    values.add(null);
    //UPDATE_DATE	更新日期
    values.add(btItemAccountDeferRec.get("MODIFY_TIME"));
    //SYS_ORG_CODE	所属部门
    values.add(null);
    //SYS_COMPANY_CODE	所属公司
    values.add("002");
    //BPM_STATUS	流程状态
    values.add(null);
    //PRO_ID	项目ID
    values.add(btItemAccountDeferRec.get("ITEMNO"));

    // AUDIT_FLOW_NO	[NULL]	12	VARCHAR2(32)	[NULL]	false	[NULL]
    values.add(btItemAccountDeferRec.get("WORKFLOWNO")== null ? null :btItemAccountDeferRec.get("WORKFLOWNO")+"-JW");
    // ORIG_ENDDATE	[NULL]	13	DATE	[NULL]	false	[NULL] 原展期到期时间
    values.add(btItemAccountDeferRec.get("OLDENDDATE"));
    // PRO_BALANCE	[NULL]	14	NUMBER(16,6)	[NULL]	false	[NULL] 项目余额
    values.add(btItemAccountDeferRec.get("ASKDEFERSUM"));
    // EXTENSION_ENDDATE	[NULL]	15	DATE	[NULL]	false	[NULL] 展期结束时间
    values.add(btItemAccountDeferRec.get("DEFERENDDATE"));
    // CUSTOM_APPLY_REASON	[NULL]	16	VARCHAR2(2000)	[NULL]	false	[NULL] 客户申请原因
    values.add(Tool.decodeUnicode(btItemDeferRec.get("CUSTOMREASON")));
    // BANK_OPINION	[NULL]	17	VARCHAR2(300)	[NULL]	false	[NULL] 银行意见
    values.add(Tool.decodeUnicode(btItemDeferRec.get("BANKNOTION")));
    // EFFECTIVE_DATE	[NULL]	18	DATE	[NULL]	false	[NULL] 生效时间
    values.add(btItemAccountDeferRec.get("DEFERBEGINDATE"));
    // PROC_ID	[NULL]	19	VARCHAR2(36)	[NULL]	false	[NULL] 流程ID
    values.add(btItemAccountDeferRec.get("WORKFLOWNO") == null ? null:btItemAccountDeferRec.get("WORKFLOWNO")+"-JW");
    // LENDING_ID	[NULL]	20	VARCHAR2(36)	[NULL]	false	[NULL]
    values.add(null);
    // TASK_ID	[NULL]	21	VARCHAR2(36)	[NULL]	false	[NULL]
    values.add(curJbpmTaskInstanceId + "-JW");
    // TASK_DEF_KEY	[NULL]	22	VARCHAR2(36)	[NULL]	false	[NULL]
    values.add(taskParam.get("taskDefKey"));
    // SOURCE_ID	[NULL]	23	VARCHAR2(36)	[NULL]	false	[NULL]
    values.add(btItemDeferRec == null ? null : getSimpleId(btItemDeferRec.get("CREATE_TIME").toString(),this.projectId));
    return values;
  }
}
